/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 * limitations under the License.
 */

package hadss.avoid_area

import android.app.Activity
import android.os.Build
import com.google.gson.Gson
import hadss.avoid_area.utils.AvoidAreaUtils
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler

/**
 * Default area of the system
 */
const val TYPE_SYSTEM = 0

/**
 * Area for Notch
 */
const val TYPE_CUTOUT = 1

/**
 * Default area of the system
 */
const val TYPE_NAVIGATION_INDICATOR = 4

class AvoidAreaMethodCallHandler(private val activity: Activity) : MethodCallHandler {
    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        if ("getWindowAvoidArea" == call.method) {
            getWindowAvoidArea(call.arguments as Int, result)
        } else if ("removeAvoidAreaListener" == call.method) {
            result.notImplemented()
        } else {
            result.notImplemented()
        }
    }

    fun getWindowAvoidArea(avoidAreaType: Int, result: MethodChannel.Result) {
        if (avoidAreaType == TYPE_SYSTEM) {
            getAvoidAreaSystem(result)
        } else if (avoidAreaType == TYPE_CUTOUT) {
            getAvoidAreaCutout(result)
        } else if (avoidAreaType == TYPE_NAVIGATION_INDICATOR) {
            getAvoidAreaNavigation(result)
        } else {
            // 手势区域和软键盘区域无相关的API获取
            result.success(Gson().toJson(AvoidArea()))
        }
    }

    /**
     * 获取状态栏避让区域
     */
    private fun getAvoidAreaSystem(result: MethodChannel.Result) {
        // 状态栏区域
        var avoidArea = AvoidArea()
        avoidArea.visible = true
        avoidArea.topRect.width = AvoidAreaUtils.getScreenWidth(activity)
        avoidArea.topRect.height = AvoidAreaUtils.getStatusBarHeight(activity)
        result.success(Gson().toJson(avoidArea))
    }


    /**
     * 获取导航栏避让区域
     */
    private fun getAvoidAreaNavigation(result: MethodChannel.Result) {
        // 底部导航栏区域
        var avoidArea = AvoidArea()
        var navigationBarHeight = AvoidAreaUtils.getNavigationBarHeight(activity)
        avoidArea.visible = AvoidAreaUtils.isNavigationBarVisible(activity)
        // 顶部间距 = 总高度 - 底部导航栏高度
        avoidArea.bottomRect.top = AvoidAreaUtils.getScreenHeight(activity) - navigationBarHeight
        avoidArea.bottomRect.height = navigationBarHeight
        result.success(Gson().toJson(avoidArea))
    }

    /**
     * 获取刘海屏避让区域
     */
    private fun getAvoidAreaCutout(result: MethodChannel.Result) {
        var avoidArea = AvoidArea()
        avoidArea.visible = false
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            var windowInsets = activity.window.decorView.rootWindowInsets
            val cutout = windowInsets.displayCutout
            cutout?.boundingRectTop?.let { updateAvoidAreaRect(avoidArea.topRect, it) }
            cutout?.boundingRectBottom?.let { updateAvoidAreaRect(avoidArea.bottomRect, it) }
            cutout?.boundingRectLeft?.let { updateAvoidAreaRect(avoidArea.leftRect, it) }
            cutout?.boundingRectRight?.let { updateAvoidAreaRect(avoidArea.rightRect, it) }
        }
        result.success(Gson().toJson(avoidArea))
    }

    private fun updateAvoidAreaRect(targetRect: Rect, sourceRect: android.graphics.Rect?) {
        if (sourceRect != null) {
            targetRect.left = sourceRect.left
            targetRect.top = sourceRect.top
            targetRect.width = sourceRect.right - sourceRect.left
            targetRect.height = sourceRect.bottom - sourceRect.top
        }
    }
}